<?php

namespace WenRuns\Laravel\Admin\Form\Field\MultiList\Field;


use Encore\Admin\Facades\Admin;

class ApiSelect extends Select
{

    /**
     * @var int|string
     */
    protected $uniqueKey = '';

    /**
     * @var array
     */
    protected $attach = [];

    /**
     * @var string
     */
    protected $method = 'GET';

    /**
     * @var string
     */
    protected $uri = '';

    /**
     * @var bool
     */
    protected $isMultiple = false;

    /**
     * @var string
     */
    protected $_changed = '';

    /**
     * @var string
     */
    protected $_updated = '';

    /**
     * @var string
     */
    protected $_beforeUpdate = '';

    /**
     * @var string
     */
    protected $_beforeClear = '';

    /**
     * @var string
     */
    protected $_cleared = '';

    /**
     * @var bool
     */
    protected $_defaultSelect = false;

    /**
     * @var bool
     */
    protected $pagination = false;

    /**
     * @var int
     */
    protected $perPage = 20;

    /**
     * @var int
     */
    protected $totalPages = 0;

    protected function get_script()
    {
        $events = json_encode([
            'cleared' => $this->_cleared,
            'beforeClear' => $this->_beforeClear,
            'changed' => $this->_changed,
            'updated' => $this->_updated,
            'beforeUpdate' => $this->_beforeUpdate,
        ], JSON_UNESCAPED_UNICODE);
        $attach = json_encode((array)$this->attach, JSON_UNESCAPED_UNICODE);
        return <<<SCRIPT
$(function(){
    let events = {$events};
    $("select.{$this->getColumnClass()}").select2({
        "allowClear":true,
        "placeholder":{
            "id":"",
            "text":"选择{$this->getPlaceholder()}"
        },
        ajax:{
            url: "{$this->uri}",
            dataType: "json",
            delay: 250,
            data: function(params){
                return {
                    q: params.term,
                    attach: {$attach},
                };
            },
            processResults: function(rst){
                let data = rst.data;
                if(data === undefined){
                    data = rst;
                }
                if(!(data instanceof Array)){
                    let arr = [];
                    for(let i in data){
                        arr.push({
                            id: i,
                            text: data[i],
                        });
                    }
                    data = arr;
                }
                return {
                    results:data,
                };
            },
            cache: true,
        },
        escapeMarkup: function(markup){
            return markup;
        },
        minimumInputLength: 0,
        templateResult: function(repo){
            return repo.text;
        },
        templateSelection: function(repo){
            if(events.changed){
                if(typeof events.changed == 'function'){
                    events.changed(repo);
                }else{
                    eval('('+events.changed+')(repo)');
                }
            }
            return repo.text;
        }
    });
});
SCRIPT;
    }

    /**
     * @return string
     */
    public function build()
    {
//        $this->wenApiScript();
        // TODO: Implement build() method.
        $name = $this->getName();
        $optionStr = '';
        foreach ($this->getOptions() as $value => $label) {
            $selected = in_array($value, (array)$this->getValue()) ? 'selected' : '';
            $optionStr .= '<option value="' . $value . '" ' . $selected . '>' . $label . '</option>';
        }
        $this->script = $this->get_script();
        if ($this->isMultiple) {
            $multiple = 'multiple';
            $name .= '[]';
        } else {
            $multiple = '';
        }
        $value = $this->getValue();
        if (is_array($value)) {
            $value = json_encode($value, JSON_UNESCAPED_UNICODE);
        }

        return <<<HTML
<div style="width: 100%;{$this->style};position: relative" class="input-group select-{$this->getUniqueKey()}">
    <span class="{$this->asterisk}"></span>
    <select class="form-control {$this->getClass()} {$this->getColumnClass()} select2-hidden-accessible" id="{$this->getClass()}" {$multiple} name="{$name}" data-value="{$value}" tabindex="-1" aria-hidden="true" data-placeholder="{$this->getPlaceholder()}" style="width:100%;" {$this->buildAttribute()}>{$optionStr}</select>
    {$this->helpText()}
</div>
HTML;
    }

    /**
     * @return string
     */
    protected function buildEmpty(): string
    {
        // TODO: Implement buildEmpty() method.
        $optionStr = '';
        $name = $this->getName();
        foreach ($this->getOptions() as $value => $label) {
            $optionStr .= '<option value="' . $value . '" >' . $label . '</option>';
        }
        $this->oneRowScript = $this->get_script();
        if ($this->isMultiple) {
            $multiple = 'multiple';
            $name .= '[]';
        } else {
            $multiple = '';
        }
        return <<<HTML
<div style="width: 100%;{$this->style};position: relative;" class="input-group select-{$this->getUniqueKey()}">
    <span class="{$this->asterisk}"></span>
    <select class="form-control {$this->getClass()} {$this->getColumnClass()} select2-hidden-accessible" id="{$this->getClass()}" {$multiple} name="{$name}" data-value="" tabindex="-1" aria-hidden="true" data-placeholder="{$this->getPlaceholder()}" style="width:100%;"  {$this->buildAttribute()}>{$optionStr}</select>
    {$this->helpText()}
</div>
HTML;
    }


//    protected function wenApiScript()
//    {
//        $options = json_encode((array)$this->options, JSON_UNESCAPED_UNICODE);
//        $attach = json_encode((array)$this->attach, JSON_UNESCAPED_UNICODE);
//        $events = json_encode([
//            'cleared' => $this->_cleared,
//            'beforeClear' => $this->_beforeClear,
//            'change' => $this->_changed,
//            'updated' => $this->_updated,
//            'beforeUpdate' => $this->_beforeUpdate,
//        ], JSON_UNESCAPED_UNICODE);
//        $token = csrf_token();
//        $script = '
//$(function(){
//    const ApiSelect = {
//        id: "' . $this->getClass() . '",
//        events: ' . $events . ',
//        defaultOptions: ' . $options . ',
//        defaultOptionsHtml: "",
//        query:{
//            url: "' . $this->uri . '",
//            method: "' . $this->method . '",
//            data:{
//                attach:' . $attach . ',
//                q: "",
//                _token: "' . $token . '",
//            }
//        },
//        state: false,
//        apiResult: null,
//        pagination: ' . ($this->pagination ? 'true' : 'false') . ',
//        multiple:' . ($this->isMultiple ? 'true' : 'false') . ',
//        page: 1,
//        perPage: ' . $this->perPage . ',
//        totalPages: ' . $this->totalPages . ',
//        uniqueKey: "' . $this->getUniqueKey() . '",
//        defaultSelect: ' . ($this->_defaultSelect ? 'true' : 'false') . ',
//        selectOptions: {},
//        matchResult:{},
//        apiQuery(){
//            let me = this;
//            let options = Object.assign({
//                success: (rst) => {
//                    try {
//                        rst = JSON.parse(rst);
//                    } catch (e) {
//                        throw new Error("api返回结果必须是json字符串")
//                    }
//                    me.apiResult = rst;
//                    if (rst.options) {
//                        me.selectOptions = rst.options;
//                    } else {
//                        me.selectOptions = rst;
//                    }
//                    if (me.pagination) {
//                        let totalPages = Number(rst.totalPages);
//                        if (!totalPages) {
//                            totalPages = 1;
//                        }
//                        me.matchResult[this.page] = {
//                            options: me.selectOptions,
//                            apiResult: me.apiResult,
//                            totalPages: totalPages,
//                        }
//                        me.totalPages = totalPages;
//                    }
//                    me.updateOptions();
//                },
//                fail: (err) => {
//                    me.changeQueryStatus("查询失败")
//                }
//            }, this.query);
//            if(this.pagination){
//                options.data.page=this.page;
//                options.data.perPage=  this.perPage;
//            }
//            me.changeQueryStatus("正在查询");
//            $.ajax(options);
//        },
//        getOptionsElement(){
//            let optionElement = document.querySelector(".select2-container--open .select2-results__options");
//            if(!optionElement){
//                return ;
//            }
//            if(!this.defaultOptionsHtml){
//                this.defaultOptionsHtml = optionElement.innerHTML;
//            }
//            return optionElement;
//        },
//        changeQueryStatus(status){
//            let optionElement = this.getOptionsElement();
//            if(optionElement){
//                optionElement.innerHTML = "<li class=\"select2-results__option select2-results__message\" style=\"color:red;\">"+status+"<\/li>"
//            }
//            return this;
//        },
//        updateOptions(){
//            let selectElement = document.getElementById(this.id);
//            let selectValues = [];
//            let selectOptionsHtml= "";
//            Array.from(selectElement.children).forEach(e=>{
//                if(e.selected){
//                    selectValues.push(e.value);
//                    selectOptionsHtml+="<option value=\""+e.value+"\" selected>"+e.innerHTML+"<\/option>";
//                }
//            });
//            if(this.selectOptions && Object.keys(this.selectOptions).length){
//                for(let value in this.selectOptions){
//                    if(selectValues.indexOf(value+"") < 0 && selectValues.indexOf(value) < 0){
//                        selectOptionsHtml += "<option value=\""+value+"\">"+this.selectOptions[value]+"<\/option>";
//                    }
//                }
//            }else{
//                selectOptionsHtml = "<option><\/option>";
//            }
//            selectElement.innerHTML = selectOptionsHtml;
//            $("select.' . $this->getClass() . '").select2({
//                "allowClear":true,
//                "placeholder":{
//                    "id":"",
//                    "text":"选择' . $this->getPlaceholder() . '"
//                },
//            });
//            let el = null;
//            if(this.multiple){
//                el = document.querySelector(".select-"+this.uniqueKey+" .select2.select2-container .selection .select2-selection");
//            }else{
//                el = document.querySelector(".select-"+this.uniqueKey+" .select2.select2-container .selection .select2-selection .select2-selection__placeholder");
//            }
//            console.log("------->",el);
//            if(el){
//                setTimeout(()=>{
//                    console.log("click......");
//                    el.click();
//                }, 100);
//            }
//            return this;
//        },
//        checkSearchFieldEvent(){
//            let me = this;
//            let field = document.querySelector(".select2-container--open .select2-search__field");
//            field.setAttribute("placeholder", "请输入关键词，按【回车】键搜索");
//            field.addEventListener("keyup", function(e){
//                if(e.keyCode == 13){
//                    me.query.data.q = field.value;
//                    me.apiQuery();
//                }
//            });
//            return this;
//        },
//        checkSelectorEvent(){
//            let me = this;
//            $(document).on("click", ".select-"+this.uniqueKey, function(e){
//                let open = e.currentTarget.querySelector(".select2-container--open");
//                if(open){
//                    me.state = true;
//                    me.checkSearchFieldEvent();
//                }else{
//                    me.state = false;
//                }
//            })
//        },
//        init(){
//            let field = document.querySelector(".select2-container--open .select2-search__field");
//            if(field){
//                field.setAttribute("placeholder", "请输入关键词，按【回车】键搜索");
//            }
//            this.checkSelectorEvent();
//        }
//    }
//    //ApiSelect.init();
//});';
//        Admin::script($script);
//    }

//    <li class="select2-results__option select2-results__option--highlighted" id="select2-list-test-0-result-64rb-2" role="treeitem" aria-selected="true">tsets</li>
//    <li class="select2-results__option select2-results__option--highlighted" id="select2-list-test-0-result-64rb-2" role="treeitem" aria-selected="false">tsets</li>
//    <li class="select2-results__option" id="select2-list-test-0-result-ps8r-3" role="treeitem" aria-selected="false">sfsdf</li>
    /**
     * 总页数
     * @param $totalPages
     * @return $this
     */
    public function totalPages($totalPages)
    {
        $this->totalPages = $totalPages;
        return $this;
    }

    /**
     * 启动分页
     * @param $bool
     * @return $this
     */
    public function pagination($bool = true)
    {
        $this->pagination = $bool;
        return $this;
    }

    /**
     * 每页显示记录
     * @param $perPage
     * @return $this
     */
    public function perPage($perPage)
    {
        $this->perPage = $perPage;
        return $this;
    }

    /**
     * select值变化钩子
     * @param $scriptFunction
     * @return $this
     */
    public function changed($scriptFunction)
    {
        $this->_changed = $this->compressHtml($scriptFunction);
        return $this;
    }

    /**
     * 更新选项后钩子
     * @param $scriptFunction
     * @return $this
     */
    public function updated($scriptFunction)
    {
        $this->_updated = $this->compressHtml($scriptFunction);
        return $this;
    }

    /**
     * 更新选项前钩子
     * @param $scriptFunction
     * @return $this
     */
    public function beforeUpdate($scriptFunction)
    {
        $this->_beforeUpdate = $this->compressHtml($scriptFunction);
        return $this;
    }

    /**
     * 清空前回调钩子
     * @param $scriptFunction
     * @return $this
     */
    public function beforeClear($scriptFunction)
    {
        $this->_beforeClear = $this->compressHtml($scriptFunction);
        return $this;
    }

    /**
     * 清空回后调钩子
     * @param $scriptFunction
     * @return $this
     */
    public function cleared($scriptFunction)
    {
        $this->_cleared = $this->compressHtml($scriptFunction);
        return $this;
    }

    /**
     * 默认选中第一个
     * @param $bool
     * @return $this
     */
    public function defaultSelect($bool = true)
    {
        $this->_defaultSelect = $bool;
        return $this;
    }


    /**
     * 压缩js字符串
     * @param $string
     * @return string
     */
    protected function compressHtml($string)
    {
        $string = preg_replace(array("/\r|\n/", '/\'/', '/\//'), array(' ', "\'", '\/'), $string);
        return $string;
    }


    /**
     * 是否多选
     * @param bool $bool
     * @return $this
     */
    public function multiple($bool = true)
    {
        $this->isMultiple = $bool;
        return $this;
    }

    /**
     * api请求地址
     * @param $url
     * @return $this
     */
    public function url($url)
    {
        $this->uri = $url;
        return $this;
    }

    /**
     * api请求方法
     * @param $method
     * @return $this
     */
    public function method($method)
    {
        $this->method = $method;
        return $this;
    }

    /**
     * api请求附加数据
     * @param $attach
     * @return $this
     */
    public function attach($attach)
    {
        $this->attach = is_array($attach) ? $attach : [$attach];
        return $this;
    }

    /**
     * select默认options
     * @param array $options
     * @return $this|\Encore\Admin\Form\Field
     */
    public function options($options = [])
    {
        $this->options = $options;
        return $this;
    }


}
